package chexuan.game.service.config;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import chexuan.game.bean.serviceParam.ConfigServiceBean;
import chexuan.game.interfaces.common.InterfaceServiceConfiguration;
import chexuan.game.interfaces.service.EnumService;
import chexuan.game.interfaces.service.InterfaceConfigService;

public class ConfigService implements InterfaceConfigService {

	private static final Log log = LogFactory.getLog(ConfigService.class);
	private static ConfigService instance = null;
	private final ConfigurationCollector collector;
	private final ConfigServiceBean bean = new ConfigServiceBean();

	public static synchronized ConfigService getInstance() {
		if (null == instance) {
			instance = new ConfigService();
		}

		return instance;
	}

	private ConfigService() {
		collector = new ConfigurationCollector();
	}

	@Override
	public EnumService getServiceType() {
		return EnumService.CONFIG_SERVICE;
	}

	@Override
	public void initialize() {
		Document document = null;

		File configDirectory = new File(bean.getConfigDirectory());
		if (!configDirectory.exists() || !configDirectory.isDirectory()) {
			configDirectory.mkdirs();
		}

		File configFile = new File(bean.getConfigFile());
		if (!configFile.exists() || !configFile.isFile()) {
			try {
				configFile.createNewFile();
			} catch (IOException e) {
				log.error("", e);
			}

			document = createDocument();
		} else {
			try {
				document = parseConfiguration(configFile.toURI().toURL());
			} catch (MalformedURLException | DocumentException e) {
				log.error("", e);
			}

			if (null == document) {
				document = createDocument();
			}
		}

		collector.setDocument(document);
	}

	@Override
	public void destroy() {
		commitConfiguration();
	}

	@Override
	public EnumService[] getDependencyServices() {
		return new EnumService[] { EnumService.LOG_SERVICE };
	}

	@Override
	public void start() {
		collector.readConfigruation(collector.getDocument());
	}

	@Override
	public void interrupt() {
		collector.writeConfigration(collector.getDocument());
	}

	private Document createDocument() {
		Document document = DocumentHelper.createDocument();
		Element root = document.addElement("chexuan");

		FileWriter out;
		try {
			out = new FileWriter(bean.getConfigFile());
			document.write(out);
			out.close();
		} catch (IOException e) {
			log.error("", e);
		}

		return document;
	}

	private Document parseConfiguration(URL url) throws DocumentException {
		SAXReader reader = new SAXReader();
		Document document = reader.read(url);
		return document;
	}

	private void commitConfiguration() {
		try {
			FileWriter out = new FileWriter(bean.getConfigFile());
			collector.commit(out);
			out.close();
		} catch (IOException e) {
			log.error("", e);
		}
	}

	@Override
	public void registerServiceConfiguration(
			InterfaceServiceConfiguration serviceConfiguration) {
		collector.registerServiceConfigration(serviceConfiguration);
	}
}
